﻿using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using Loong.Authentication;
using Loong.Extensions;

namespace Loong.AspNetCore.Authentication
{
    public class JwtTokenService : IJwtTokenService
    {
        private readonly JwtTokenOptions _jwtTokenOptions;

        public JwtTokenService(IOptionsMonitor<JwtTokenOptions> options)
        {
            _jwtTokenOptions = options.CurrentValue;
        }

        public JwtToken CreateToken(ClaimsIdentity claimsIdentity, TimeSpan? validTime = null)
        {
            var securityTokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = claimsIdentity,
                Audience = _jwtTokenOptions.ValidAudience,
                Issuer = _jwtTokenOptions.ValidIssuer,
                IssuedAt = DateTime.Now,
                Expires = DateTime.Now.Add(validTime.HasValue ? validTime.Value : TimeSpan.FromMinutes(_jwtTokenOptions.ValidMinutes)),
                SigningCredentials = new SigningCredentials(_jwtTokenOptions.GetSecurityKey(), SecurityAlgorithms.HmacSha256Signature)
            };
            var jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
            var token = jwtSecurityTokenHandler.CreateToken(securityTokenDescriptor);
            var tokenString = jwtSecurityTokenHandler.WriteToken(token);

            var jwtToken = new JwtToken
            {
                access_token = tokenString,
                expires_in = securityTokenDescriptor.Expires.Value.ToUnixTimestamp().To<int>(),
                token_type = JwtBearerDefaults.AuthenticationScheme
            };

            return jwtToken;
        }
    }
}
